package com

import com.Main.Companion.runPath
import com.amazonaws.ClientConfiguration
import com.amazonaws.auth.AWSCredentialsProvider
import com.amazonaws.auth.AWSStaticCredentialsProvider
import com.amazonaws.auth.BasicAWSCredentials
import com.amazonaws.auth.profile.internal.AwsProfileNameLoader
import com.amazonaws.client.builder.AwsClientBuilder
import com.amazonaws.regions.Regions
import com.amazonaws.services.cloudfront.AmazonCloudFront
import com.amazonaws.services.cloudfront.AmazonCloudFrontClientBuilder
import com.amazonaws.services.s3.AmazonS3
import com.amazonaws.services.s3.AmazonS3ClientBuilder
import com.entity.PackCmd
import org.slf4j.LoggerFactory
import kotlin.io.path.Path
import kotlin.io.path.exists
import kotlin.io.path.pathString
import kotlin.io.path.readLines

class AwsUtils(callable: (() -> Unit)? = null) {

    companion object {
        lateinit var awsUtils: AwsUtils
    }

    @JvmField
    val packCmd: PackCmd

    /**
     * 已经登录的s3
     */
    var s3Client: AmazonS3? = null
        private set

    /**
     * 当前使用的配置
     */
    var credentialsProvider: AWSCredentialsProvider? = null
        private set

    init {
        awsUtils = this
        this.packCmd = PackCmd(callable)
    }

    /**
     * 检查账户是否有问题
     */
    fun checkAccount(): Boolean {
        if (packCmd.accessKeyId.isNullOrBlank() || packCmd.accessKeySecret.isNullOrBlank()) {
            // 如果有一个值是 null
            if (packCmd.profile != null) { // 有传入别名
                System.setProperty(
                    AwsProfileNameLoader.AWS_PROFILE_SYSTEM_PROPERTY,
                    packCmd.profile!!
                ) // 写入系统变量里面  方便 aws sdk 自动获取
            } else {
                packCmd.profile = AwsProfileNameLoader.DEFAULT_PROFILE_NAME // 设置默认值
            }
            println("*********  使用缓存账户 " + packCmd.profile + " 登录  *********")
            this.s3Client = this.build(null).build()
            val awsCredentials = credentialsProvider!!.credentials
            packCmd.accessKeyId = awsCredentials.awsAccessKeyId
            packCmd.accessKeySecret = awsCredentials.awsSecretKey
            if (packCmd.accessKeyId.isNullOrBlank() || packCmd.accessKeySecret.isNullOrBlank()) {
                println("error : profile=[" + packCmd.profile + "]")
                return true
            }
        } else {
            // 手动输入账号密码
            this.s3Client = this.build(this.awsStaticCredentialsProvider).build()
        }
        return false
    }

    fun build(provider: AWSCredentialsProvider?): AmazonS3ClientBuilder {
        println("开始连接AWS S3服务器。。。")
        val amazonS3ClientBuilder = AmazonS3ClientBuilder.standard()
            .withRegion(Regions.EU_CENTRAL_1)
        configProxy(amazonS3ClientBuilder)
        if (provider != null) {
            amazonS3ClientBuilder.withCredentials(awsStaticCredentialsProvider)
        }
        credentialsProvider = amazonS3ClientBuilder.credentials
        return amazonS3ClientBuilder
    }

    fun initAmazonCloudFront(count: Int = 0): AmazonCloudFront {
        println("${if (count > 0) "第${count}次" else ""}初始化 cloudfront...")
        return runCatching {
            // 初始化服务器
            AmazonCloudFrontClientBuilder.standard()
                .withRegion(Regions.EU_CENTRAL_1).withCredentials(credentialsProvider)
                .also {
                    configProxy(it)
                }.build()
        }.onFailure {
            Thread.sleep(1000)
            initAmazonCloudFront(count + 1)
        }.getOrThrow()
    }

    private fun configProxy(awsClientBuilder: AwsClientBuilder<*, *>) {
        // 添加代理
        val file = Path(runPath.pathString, "proxy.conf")
        if (file.exists()) { // 存在代理配置
            try {
                val strings = file.readLines()
                var host: String? = null
                var port: String? = null
                for (str in strings) {
                    val map = str.split("=")
                    if (map.size == 2) {
                        if (map[0] == "proxyHost") {
                            host = map[1]
                        } else if (map[0] == "proxyPort") {
                            port = map[1]
                        }
                    }
                }
                if (!host.isNullOrBlank() && !port.isNullOrBlank()) {
                    awsClientBuilder.withClientConfiguration(
                        getCreateClientConfiguration(host, port.toInt())
                    )
                    LoggerFactory.getLogger(javaClass).info("代理：$host:$port")
                } else {
                    println("代理配置数据有错误：$strings")
                    LoggerFactory.getLogger(javaClass).info("代理配置数据有错误：$strings")
                }
            } catch (_: Exception) {
            }
        } else {
            LoggerFactory.getLogger(javaClass).info("未找到代理配置：" + file.pathString)
            println("未找到代理配置：" + file.pathString)
        }
    }

    /**
     * 创建代理
     */
    private fun getCreateClientConfiguration(host: String?, port: Int): ClientConfiguration {
        return ClientConfiguration().also {
            it.withProxyHost(host)
            it.withProxyPort(port)
//            it.withProtocol(Protocol.HTTPS);
        }
    }


    private val awsStaticCredentialsProvider: AWSStaticCredentialsProvider
        get() {
            val awsCreds = BasicAWSCredentials(packCmd.accessKeyId, packCmd.accessKeySecret)
            return AWSStaticCredentialsProvider(awsCreds)
        }

}
